package ar.com.fiuba.ElectronicCircuitAnalyst.infrastructure.db4o.repository;

import java.util.Collection;

import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.repository.Repository;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.exceptions.DuplicateElementException;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.exceptions.ElementNotFoundException;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;

public abstract class RepositoryImpl<T> implements Repository<T> {

	private ObjectContainer db;
	
	private Class<? extends T> clazz;
	
	public RepositoryImpl(Class<? extends T> clazz) {
		super();
		this.clazz = clazz;
	}
	
	public Collection<T> findAll() {
		ObjectSet<T> result = db.queryByExample(clazz);
		return (Collection<T>) result;
	}

	public T update(T t) {
		this.getDb().store(t);
		return t;
	}

	public T save(T t) throws DuplicateElementException {
		
		long id = this.getDb().ext().getID(t);
		
		if (id != 0)
			throw new DuplicateElementException("The Object" + t.toString() + "has already persisted");
		
		this.getDb().store(t);
		//this.getDb().commit(); El commit termina la transaccion. Ver como sacar el commit de aca. AOP?
		return t;
	}

	
	public Collection<T> get(T t) {
		ObjectSet<T> result = this.getDb().queryByExample(t);
		return result;
	}
	

	public void remove(T t) throws ElementNotFoundException {
		
		long id = this.getDb().ext().getID(t);
		
		if( id == 0 ){
			throw new ElementNotFoundException("No object found for the prototipe: " + t.toString());
		}
		
		this.getDb().delete(t);
	}

	/**
	 * @return the db
	 */
	public ObjectContainer getDb() {
		return db;
	}

	/**
	 * @param db the db to set
	 */
	public void setDb(ObjectContainer db) {
		this.db = db;
	}

}
